import os

import numpy as np
from deepface import DeepFace
from fastapi import APIRouter, Form
from sqlmodel import select

from app.models import SessionDep
from app.models.face import Face, Gender
from app.utils.face import check_face, find_most_similar_face
from app.utils.model import paginated
from app.utils.response import success, error

router = APIRouter(prefix="/face", tags=["face"])


@router.post("/create")
def face_create(
        session: SessionDep,
        name: str = Form(...),
        gender: Gender = Form(...),
        mobile: str = Form(...),
        face_image: str = Form(...),
):
    face = Face(name=name, gender=gender, mobile=mobile, face_image=face_image)

    # 检查文件或目录是否存在
    if not os.path.exists(face.face_image):
        return error("文件不存在")

    # 检查人脸是否存在
    if not check_face(face.face_image):
        return error("图片中没有人脸,或者出现多个人脸")

    # 提取人脸特征
    embedding = DeepFace.represent(img_path=face.face_image)
    face.face_vector = embedding[0]["embedding"]
    face.face_area = embedding[0]["facial_area"]
    face.face_conf = str(embedding[0]["face_confidence"])

    # 写入到数据库
    session.add(face)
    session.commit()
    session.refresh(face)

    # 返回结果
    return success("创建成功")


@router.post("/delete")
def face_delete(
        session: SessionDep,
        id: int = Form(...),
):
    # 查询人脸是否存在
    face = session.exec(select(Face).where(Face.id == id)).first()
    if not face:
        return error("人脸不存在")

    # 删除数据
    session.delete(face)
    session.commit()

    # 返回结果
    return success("删除成功")


@router.post("/detail")
def face_detail(
        session: SessionDep,
        id: int = Form(...),
):
    # 查询人脸是否存在
    face = session.exec(select(Face).where(Face.id == id)).first()
    if not face:
        return error("人脸不存在")

    # 返回结果
    return success("获取成功", face)


@router.post("/lists")
def face_lists(
        session: SessionDep,
        page: int = Form(default=1),
        page_size: int = Form(default=10),
):
    # 查询人脸
    lists = select(Face).order_by(Face.id.desc())

    # 数据分页
    lists = paginated(lists, session, page, page_size)

    # 排除字段
    lists = [item.dict(exclude={"face_vector"}) for item in lists["data"]]

    # 返回结果
    return success("获取成功", lists)


@router.post("/search")
def face_search(
        session: SessionDep,
        face_image: str = Form(...),
):
    # 检查文件或目录是否存在
    if not os.path.exists(face_image):
        return error("文件不存在")

    # 检查人脸是否存在
    if not check_face(face_image):
        return error("图片中没有人脸,或者出现多个人脸")

    # 提取人脸特征
    embedding = DeepFace.represent(img_path=face_image)

    # 查询数据库中所有人脸
    feature_vectors = []
    faces = session.exec(select(Face)).all()

    # 提取人脸特征向量
    for face in faces:
        feature_vectors.append(face.face_vector)

    # 查找相似的人脸
    closest_index = find_most_similar_face(embedding[0]["embedding"], np.array(feature_vectors))

    # 没有找到相似的人脸
    if closest_index == -1:
        return error("识别失败")

    # 排除字段
    faces = [item.dict(exclude={"face_vector"}) for item in faces]

    # 返回结果
    return success("获取成功", faces[closest_index])
